package com.yuncheng.oaApi.controller;

import java.io.File;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.yuncheng.entity.YcSysOrg;
import com.yuncheng.oaApi.constant.OaBusinessConstant;
import com.yuncheng.oaApi.constant.OaCommonFlowConstant;
import com.yuncheng.oaApi.constant.OaLogConstant;
import com.yuncheng.spcyApi.alog.annotation.Log;
import com.yuncheng.oaApi.constant.NkConstant;
import com.yuncheng.oaApi.vo.HttpResultVo;
import com.yuncheng.oaApi.vo.NkCfVo;
import com.yuncheng.oaApi.vo.YszbVo;
import com.yuncheng.spcyApi.service.ISpcyLogService;
import org.apache.commons.collections.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yuncheng.oaApi.entity.*;
import com.yuncheng.exception.BusinessException;
import com.yuncheng.oaApi.mapper.NkRsYszbtzMapper;
import com.yuncheng.oaApi.service.*;
import com.yuncheng.oaApi.utils.GetUuIdUtils;
import com.yuncheng.oaApi.utils.OaLocalFileUploadUtils;
import com.yuncheng.spcyApi.utils.MyExcelUtils;
import com.yuncheng.vo.*;
import com.yuncheng.annotation.AutoLog;
import com.yuncheng.utils.I18nUtil;
import com.yuncheng.common.base.controller.BaseController;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import utils.DateConversionUtils;
import utils.LogUtils;
import utils.ObjectToMapUtils;

/**
 * @Description: 内控-预算指标台账
 * @Author: lhb
 * @Date: 2023-11-20
 * @Version: V1.0
 */
@Api(tags = "NK_内控-预算指标台账接口")
@RestController
@RequestMapping("/api/spzx-oa/nkRsYszbtz")
public class NkRsYszbtzController {

    private static final Logger log = LoggerFactory.getLogger(NkRsYszbtzController.class);

    @Resource
    private INkRsYszbtzService nkRsYszbtzService;

    @Resource
    @Lazy
    private OaLocalFileUploadUtils oaLocalFileUploadUtils;

    @Resource
    @Lazy
    private MyExcelUtils myExclUtil;

    @Resource
    @Lazy
    private INkRsXmyszbbService nkRsXmyszbbService;

    @Resource
    @Lazy
    private IOaYcSysOrgService ycSysOrgService;

    @Resource
    @Lazy
    private INkRsYszbczjlService nkRsYszbczjlService;

    @Resource
    @Lazy
    private ISpcyLogService spcyLogService;

    @Resource
    @Lazy
    private NkRsYszbtzMapper nkRsYszbtzMapper;


    @Resource
    private INkRsNdService nkRsNdService;



    /**
     * 分页列表查询
     *
     * @param nkRsYszbtz
     * @param pageNo
     * @param pageSize
     * @param
     * @return
     */
    @AutoLog(value = "内控-预算指标台账-分页列表查询")
    @ApiOperation(value = "内控-预算指标台账-分页列表查询")
    @GetMapping(value = "/list")
    public HttpResult<?> queryPageList(NkRsYszbtz nkRsYszbtz, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        LambdaQueryWrapper<NkRsYszbtz> queryWrapper = new LambdaQueryWrapper<>();
        //预算项目名称
        queryWrapper.like(StringUtils.isNotBlank(nkRsYszbtz.getFysxmmc()),NkRsYszbtz::getFysxmmc,nkRsYszbtz.getFysxmmc());
        //指标摘要
        queryWrapper.like(StringUtils.isNotBlank(nkRsYszbtz.getFzbzy()),NkRsYszbtz::getFzbzy,nkRsYszbtz.getFzbzy());
        //功能分类编码
        queryWrapper.like(StringUtils.isNotBlank(nkRsYszbtz.getFgnflbm()),NkRsYszbtz::getFgnflbm,nkRsYszbtz.getFgnflbm());
        //功能分类名称
        queryWrapper.like(StringUtils.isNotBlank(nkRsYszbtz.getFgnflmc()),NkRsYszbtz::getFgnflmc,nkRsYszbtz.getFgnflmc());
        //部门经济分类编码
        queryWrapper.like(StringUtils.isNotBlank(nkRsYszbtz.getFbmjjflbm()),NkRsYszbtz::getFbmjjflbm,nkRsYszbtz.getFbmjjflbm());
        //部门经济分类名称
        queryWrapper.like(StringUtils.isNotBlank(nkRsYszbtz.getFbmjjflmc()),NkRsYszbtz::getFbmjjflmc,nkRsYszbtz.getFbmjjflmc());
        //政府经济分类编码
        queryWrapper.like(StringUtils.isNotBlank(nkRsYszbtz.getFzfjjflbm()),NkRsYszbtz::getFzfjjflbm,nkRsYszbtz.getFzfjjflbm());
        //政府经济分类名称
        queryWrapper.like(StringUtils.isNotBlank(nkRsYszbtz.getFzfjjflmc()),NkRsYszbtz::getFzfjjflmc,nkRsYszbtz.getFzfjjflmc());
        //支出项目类别编码
        queryWrapper.like(StringUtils.isNotBlank(nkRsYszbtz.getFzcxmlbbm()),NkRsYszbtz::getFzcxmlbbm,nkRsYszbtz.getFzcxmlbbm());
        //支出项目类别名称
        queryWrapper.like(StringUtils.isNotBlank(nkRsYszbtz.getFzcxmlbmc()),NkRsYszbtz::getFzcxmlbmc,nkRsYszbtz.getFzcxmlbmc());
        //指标来源名称
        queryWrapper.like(StringUtils.isNotBlank(nkRsYszbtz.getFzblymc()),NkRsYszbtz::getFzblymc,nkRsYszbtz.getFzblymc());
        //预算来源名称
        queryWrapper.like(StringUtils.isNotBlank(nkRsYszbtz.getFyslymc()),NkRsYszbtz::getFyslymc,nkRsYszbtz.getFyslymc());


        //是否已完全拆分 /1 已拆分/0 未拆分
       if (nkRsYszbtz.getFsfywqcf() != null){
           queryWrapper.eq(NkRsYszbtz::getFsfywqcf,nkRsYszbtz.getFsfywqcf());
       }
       queryWrapper.orderByAsc(NkRsYszbtz::getFxh);




       Page<NkRsYszbtz> page = new Page<>(pageNo, pageSize);
       IPage<NkRsYszbtz> pageList = nkRsYszbtzService.page(page, queryWrapper);
        return HttpResult.ok(pageList);
    }



    @AutoLog(value = "内控-预算指标台账进度组装-当前页")
    @ApiOperation(value = "内控-预算指标台账进度组装-当前页")
    @GetMapping(value = "/treelists")
    public HttpResult<?> TzTreeLists(YszbVo yszbvo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                     @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, String fbm){

        //添加一个全局的年度查询 ，查询年度表当前选择的年度，如果没有选择，那就为默认当前年度
        String fnd = "";
        List<NkRsnd> nkRsnds = nkRsNdService.list(new LambdaQueryWrapper<NkRsnd>()
                .eq(NkRsnd::getFsfxz,OaCommonFlowConstant.NDXZ_YES));
        if (CollectionUtils.isNotEmpty(nkRsnds)){
             fnd = nkRsnds.get(0).getFnd();
        }else {
            fnd = DateConversionUtils.DateToYear(new Date());
        }


        if (StringUtils.isNotBlank(fbm)){
            yszbvo.setFbm(fbm);
        }


        yszbvo.setFnd(fnd);


        Page<YszbVo> page = new Page<>(pageNo, pageSize);
        IPage<YszbVo> list = nkRsYszbtzMapper.treeList(page,yszbvo);

        List<YszbVo> records = list.getRecords();

        for (YszbVo yszb :records){
            LambdaQueryWrapper<NkRsXmyszbb> wrapper =  new LambdaQueryWrapper<>();
            wrapper.eq(NkRsXmyszbb::getFtzid, yszb.getKey());
            List<NkRsXmyszbb> zblist = nkRsXmyszbbService.list(wrapper);
            yszb.setChildren(zblist);
        }

        list.setRecords(records);

        IPage<YszbVo> pageInfo = list;
        List<YszbVo> dataList = pageInfo.getRecords();

        ArrayList idlist = new ArrayList();
        //循环这个list 然后拿到所有的查询id
        for(YszbVo lists:dataList){
            String id = lists.getId();
            idlist.add(id);
        }



        Map tzmap = new HashMap<>();
        Map pagemap = new HashMap<>();

        ArrayList pagelist = new ArrayList();


        List<NkRsYszbtz> tzlisted = nkRsYszbtzService.list(new LambdaQueryWrapper<NkRsYszbtz>()
                .eq(NkRsYszbtz::getFnd, fnd));
        if (CollectionUtils.isNotEmpty(tzlisted)){
            BigDecimal fzzb = new BigDecimal(0);
            BigDecimal fyzfje = new BigDecimal(0);
            BigDecimal fzbjy = new BigDecimal(0);
            BigDecimal fzcjd = new BigDecimal(0);



            for (NkRsYszbtz tzlists:tzlisted){
                fzzb = fzzb.add((new BigDecimal(Optional.ofNullable(tzlists.getFzzb()).orElseGet(() -> "0"))));
                fyzfje = fyzfje.add(new BigDecimal(Optional.ofNullable(tzlists.getFyzfje()).orElseGet(() -> "0")));
                fzbjy = fzbjy.add(new BigDecimal(Optional.ofNullable(tzlists.getFzbjy()).orElseGet(() -> "0")));
            }
            //总台账支出进度为 =  总的指标/总的结余
            BigDecimal percentage = fyzfje.divide(fzzb, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));

            // 检查小数部分是否为零，如果为零则返回整数部分
            if (percentage.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0) {
                percentage = percentage.setScale(0, RoundingMode.DOWN);
            } else {
                percentage = percentage.setScale(2, RoundingMode.HALF_UP); // 保留两位小数
            }

            String percentageString = percentage.toPlainString() + "%";
            tzmap.put("fzzb",fzzb);
            tzmap.put("fyzfje",fyzfje);
            tzmap.put("fzbjy",fzbjy);
            tzmap.put("fzcjd",percentageString);
        }



        if (CollectionUtils.isNotEmpty(idlist)){
            BigDecimal fzzb = new BigDecimal(0);
            BigDecimal fyzfje = new BigDecimal(0);
            BigDecimal fzbjy = new BigDecimal(0);
            BigDecimal fzcjd = new BigDecimal(0);

//            List<String> pagelists = Arrays.asList(ids.split(",|，"));
            List<NkRsYszbtz> rsYszbtzLists = nkRsYszbtzService.listByIds(idlist);
            for (NkRsYszbtz rsYszbtzList:rsYszbtzLists){
                fzzb = fzzb.add((new BigDecimal(Optional.ofNullable(rsYszbtzList.getFzzb()).orElseGet(() -> "0"))));
                fyzfje = fyzfje.add(new BigDecimal(Optional.ofNullable(rsYszbtzList.getFyzfje()).orElseGet(() -> "0")));
                fzbjy = fzbjy.add(new BigDecimal(Optional.ofNullable(rsYszbtzList.getFzbjy()).orElseGet(() -> "0")));
            }
            // 计算百分比，保留四位小数
            BigDecimal percentage = fyzfje.divide(fzzb, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));

            // 检查小数部分是否为零，如果为零则返回整数部分
            if (percentage.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0) {
                percentage = percentage.setScale(0, RoundingMode.DOWN);
            } else {
                percentage = percentage.setScale(2, RoundingMode.HALF_UP); // 保留两位小数
            }

            String percentageString = percentage.toPlainString() + "%";


            pagemap.put("fzzb",fzzb);
            pagemap.put("fyzfje",fyzfje);
            pagemap.put("fzbjy",fzbjy);
            pagemap.put("fzcjd",percentageString);


        }
//        pagelist.add(tzmap);
        pagelist.add(pagemap);

        return HttpResult.ok(pagelist);



    }



    /**
     * 总台账进度
     * 总指标 已支付 指标结余  支出进度
     */
    @AutoLog(value = "内控-预算指标台账-总台账进度/当前页进度")
    @ApiOperation(value = "内控-总台账进度")
    @GetMapping(value = "/allTzJd")
    public HttpResult<?> allTzJd(String ids,String nd){
        Map tzmap = new HashMap<>();
        Map pagemap = new HashMap<>();

        ArrayList pagelist = new ArrayList();

        //添加一个全局的年度查询 ，查询年度表当前选择的年度，如果没有选择，那就为默认当前年度
        String fnd = "";
        List<NkRsnd> nkRsnds = nkRsNdService.list(new LambdaQueryWrapper<NkRsnd>()
                .eq(NkRsnd::getFsfxz,OaCommonFlowConstant.NDXZ_YES));
        if (CollectionUtils.isNotEmpty(nkRsnds)){
            fnd = nkRsnds.get(0).getFnd();
        }else {
            fnd = DateConversionUtils.DateToYear(new Date());
        }





            List<NkRsYszbtz> tzlisted = nkRsYszbtzService.list(new LambdaQueryWrapper<NkRsYszbtz>()
                    .eq(NkRsYszbtz::getFnd, fnd));
            if (CollectionUtils.isNotEmpty(tzlisted)){
                BigDecimal fzzb = new BigDecimal(0);
                BigDecimal fyzfje = new BigDecimal(0);
                BigDecimal fzbjy = new BigDecimal(0);
                BigDecimal fzcjd = new BigDecimal(0);



                for (NkRsYszbtz tzlists:tzlisted){
                    fzzb = fzzb.add(new BigDecimal(Optional.ofNullable(tzlists.getFzzb()).orElseGet(() -> "0")));
                    fyzfje = fyzfje.add(new BigDecimal(Optional.ofNullable(tzlists.getFyzfje()).orElseGet(() -> "0")));
                    fzbjy = fzbjy.add(new BigDecimal(Optional.ofNullable(tzlists.getFzbjy()).orElseGet(() -> "0")));
                }
                //总台账支出进度为 =  总的指标/总的结余
                BigDecimal percentage = fyzfje.divide(fzzb, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));

                // 检查小数部分是否为零，如果为零则返回整数部分
                if (percentage.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0) {
                    percentage = percentage.setScale(0, RoundingMode.DOWN);
                } else {
                    percentage = percentage.setScale(2, RoundingMode.HALF_UP); // 保留两位小数
                }

                String percentageString = percentage.toPlainString() + "%";
                tzmap.put("fzzb",fzzb);
                tzmap.put("fyzfje",fyzfje);
                tzmap.put("fzbjy",fzbjy);
                tzmap.put("fzcjd",percentageString);
        }



        if (StringUtils.isNotBlank(ids)){
            BigDecimal fzzb = new BigDecimal(0);
            BigDecimal fyzfje = new BigDecimal(0);
            BigDecimal fzbjy = new BigDecimal(0);
            BigDecimal fzcjd = new BigDecimal(0);

            List<String> pagelists = Arrays.asList(ids.split(",|，"));
            List<NkRsYszbtz> rsYszbtzLists = nkRsYszbtzService.listByIds(pagelists);
            for (NkRsYszbtz rsYszbtzList:rsYszbtzLists){
                fzzb = fzzb.add((new BigDecimal(rsYszbtzList.getFzzb())));
                fyzfje = fyzfje.add(new BigDecimal(rsYszbtzList.getFyzfje()));
                fzbjy = fzbjy.add(new BigDecimal(rsYszbtzList.getFzbjy()));
            }
            // 计算百分比，保留四位小数
            BigDecimal percentage = fyzfje.divide(fzzb, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));

            // 检查小数部分是否为零，如果为零则返回整数部分
            if (percentage.remainder(BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0) {
                percentage = percentage.setScale(0, RoundingMode.DOWN);
            } else {
                percentage = percentage.setScale(2, RoundingMode.HALF_UP); // 保留两位小数
            }

            String percentageString = percentage.toPlainString() + "%";


            pagemap.put("fzzb",fzzb);
            pagemap.put("fyzfje",fyzfje);
            pagemap.put("fzbjy",fzbjy);
            pagemap.put("fzcjd",percentageString);


        }
        pagelist.add(tzmap);
        pagelist.add(pagemap);

        return HttpResult.ok(pagelist);

    }


    /**
     * 组装数据
     * @param
     * @return
     */
    @AutoLog(value = "内控-预算指标台账组装")
    @ApiOperation(value = "内控-预算指标台账组装")
    @GetMapping(value = "/treelist")
    public HttpResult<?> TzTreeList(YszbVo yszbvo,@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                              @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,String fbm){

        if (StringUtils.isNotBlank(fbm)){
            yszbvo.setFbm(fbm);
        }


        //添加一个全局的年度查询 ，查询年度表当前选择的年度，如果没有选择，那就为默认当前年度
        String fnd = "";
        List<NkRsnd> nkRsnds = nkRsNdService.list(new LambdaQueryWrapper<NkRsnd>()
                .eq(NkRsnd::getFsfxz,OaCommonFlowConstant.NDXZ_YES));
        if (CollectionUtils.isNotEmpty(nkRsnds)){
            fnd = nkRsnds.get(0).getFnd();
        }else {
            fnd = DateConversionUtils.DateToYear(new Date());
        }
        yszbvo.setFnd(fnd);

        Page<YszbVo> page = new Page<>(pageNo, pageSize);
        IPage<YszbVo> list = nkRsYszbtzMapper.treeList(page,yszbvo);

        List<YszbVo> records = list.getRecords();

        for (YszbVo yszb :records){
            LambdaQueryWrapper<NkRsXmyszbb> wrapper =  new LambdaQueryWrapper<>();
            wrapper.eq(NkRsXmyszbb::getFtzid, yszb.getKey());
            List<NkRsXmyszbb> zblist = nkRsXmyszbbService.list(wrapper);
            yszb.setChildren(zblist);
        }

        list.setRecords(records);
        return HttpResult.ok(list);

    }

    @AutoLog(value = "内控-新预算指标台账组装")
    @ApiOperation(value = "内控-新预算指标台账组装")
    @GetMapping(value = "/newtreelist")
    public HttpResult<?> NewTzTreeList(YszbVo yszbvo,@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                    @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize){
        Page<YszbVo> page = new Page<>(pageNo, pageSize);
        IPage<YszbVo> list = nkRsYszbtzMapper.treeList(page,yszbvo);

        List<YszbVo> records = list.getRecords();

        for (YszbVo yszb :records){
            LambdaQueryWrapper<NkRsXmyszbb> wrapper =  new LambdaQueryWrapper<>();
            wrapper.eq(NkRsXmyszbb::getParentid, yszb.getId());
            List<NkRsXmyszbb> zblist = nkRsXmyszbbService.list(wrapper);
            yszb.setChildren(zblist);
        }
        list.setRecords(records);
        return HttpResult.ok(list);

    }



    /**
     * 添加
     *
     * @param nkRsYszbtz
     * @return
     */
    @AutoLog(value = "内控-预算指标台账-添加")
    @ApiOperation(value = "内控-预算指标台账-添加")
    @PostMapping(value = "/add")
    public HttpResult<?> add(@RequestBody NkRsYszbtz nkRsYszbtz) {
        HttpResult<String> result = new HttpResult(true);

        if (StringUtils.isBlank(nkRsYszbtz.getFzzb())){
            throw new BusinessException("总指标为空！");
        }
        if (StringUtils.isBlank(nkRsYszbtz.getFyzfje())){
            nkRsYszbtz.setFyzfje("0");
        }
        if (StringUtils.isBlank(nkRsYszbtz.getFzbjy())){
            nkRsYszbtz.setFzbjy("0");
        }
        if (StringUtils.isBlank(nkRsYszbtz.getFzcjd())){
            nkRsYszbtz.setFzcjd("0");
        }
        if (StringUtils.isBlank(nkRsYszbtz.getFnd())){
            nkRsYszbtz.setFnd(DateConversionUtils.DateToYear(new Date()));
        }


        BigDecimal zzbBd = new BigDecimal(nkRsYszbtz.getFzzb());
        BigDecimal yzfje = new BigDecimal(nkRsYszbtz.getFyzfje());

        if ((zzbBd.compareTo(yzfje)) == -1){
            throw new BusinessException("支付金额不能比总指标大！");
        }

        BigDecimal zbjyBd = zzbBd.subtract(yzfje);
        nkRsYszbtz.setFzbjy(zbjyBd.toString());

        BigDecimal zcjd = yzfje.divide(zzbBd, 3, BigDecimal.ROUND_HALF_UP);
        nkRsYszbtz.setFzcjd(zcjd.toString());

        nkRsYszbtz.setFsfywqcf(NkConstant.NK_CWYS_WCF);

        nkRsYszbtzService.save(nkRsYszbtz);
        result.setResult(nkRsYszbtz.getId());
        result.setMessage(I18nUtil.message("save.success"));
        return result;
    }

    /**
     * 编辑
     *
     * @param nkRsYszbtz
     * @return
     */
    @AutoLog(value = "内控-预算指标台账-编辑")
    @ApiOperation(value = "内控-预算指标台账-编辑")
    @PutMapping(value = "/edit")
    public HttpResult<?> edit(@RequestBody NkRsYszbtz nkRsYszbtz) {
        nkRsYszbtzService.updateById(nkRsYszbtz);
        return HttpResult.ok(I18nUtil.message("update.success"));
    }


    /**
     * @param
     * @return
     */
    @AutoLog(value = "内控-拆分的预算项目指标")
    @ApiOperation(value = "内控-拆分的预算项目指标")
    @PutMapping(value = "/CfysList")
    public HttpResult<?> CfysList(String id) {
        List<NkRsXmyszbb> xmyszbbs = nkRsXmyszbbService.list(new LambdaQueryWrapper<NkRsXmyszbb>().eq(NkRsXmyszbb::getFtzid, id));
        return HttpResult.ok(xmyszbbs);
    }

    /**
     * @param
     * @return
     */
    @AutoLog(value = "内控-项目预算指标的操作记录")
    @ApiOperation(value = "内控-项目预算指标的操作记录")
    @PutMapping(value = "/SzjlList")
    public HttpResult<?> SzjlList(String id) {
        List<NkRsYszbczjl> list = nkRsYszbczjlService.list(new LambdaQueryWrapper<NkRsYszbczjl>().eq(NkRsYszbczjl::getFyszbid, id));
        return HttpResult.ok(list);
    }




    /**
     * 拆分预算指标台账
     */
    @AutoLog(value = "内控-预算指标台账-拆分")
    @ApiOperation(value = "内控-预算指标台账-拆分")
    @PostMapping(value = "/cfyszbtz")
    public HttpResult<?> cfyszbtz(@RequestBody NkCfVo nkCfVo) throws InvocationTargetException, IllegalAccessException {
        if (StringUtils.isBlank(nkCfVo.getFtzid())){
            throw new BusinessException("台账参数为空！");
        }

        NkRsYszbtz nkRsYszbtz = nkRsYszbtzService.getById(nkCfVo.getFtzid());
        if (nkRsYszbtz == null){
            throw new BusinessException("没有相匹配的台账数据！");
        }

        //拿到预算指标台账 先比较 结余 和 拆分的总指标
        BigDecimal zzbDecimal = new BigDecimal(nkCfVo.getFzzb());

        if (StringUtils.isBlank(nkRsYszbtz.getFzbjy())){
            BigDecimal zzbBd = new BigDecimal(Optional.ofNullable(nkRsYszbtz.getFzzb()).orElseGet(() -> "0"));
            BigDecimal yzfjeBd = new BigDecimal(Optional.ofNullable(nkRsYszbtz.getFyzfje()).orElseGet(() -> "0"));
            BigDecimal zbjyBd = zzbBd.subtract(yzfjeBd);
            nkRsYszbtz.setFzbjy(zbjyBd.toString());
        }

        BigDecimal zbjyDecimal = new BigDecimal(nkRsYszbtz.getFzbjy());
        //如果指标结余为0 那就直接报错
        int zbjy2 = zbjyDecimal.compareTo(new BigDecimal("0"));
        if (zbjy2 == 0){
            throw new BusinessException("当前台账已全部拆分完成，请勿再次拆分!");
        }

        //如果当前对象小于val，则返回负整数；如果当前对象等于val，则返回0；如果当前对象大于val，则返回正整数
        int compare = zzbDecimal.compareTo(zbjyDecimal);
        if (compare > 0){
            throw new BusinessException("拆分的总指标大于当前台账指标结余，请重新输入总指标");
        }

        BigDecimal jcjd = new BigDecimal(Optional.ofNullable(nkRsYszbtz.getFzcjd()).orElseGet(()->"0"));
        if ((jcjd.compareTo(new BigDecimal("1.0"))) == 0){
            throw new BusinessException("当前指标台账已拆分完成，请勿拆分");
        }

        NkRsXmyszbb nkRsXmyszbb = new NkRsXmyszbb();
        //项目预算指标表  要赋值的对象 <-数据源对象
        BeanUtils.copyProperties(nkRsXmyszbb, nkCfVo);

        nkRsXmyszbb.setFbmjjflbm(Optional.ofNullable(nkRsYszbtz.getFbmjjflbm()).orElseGet(()->""));
        nkRsXmyszbb.setFbmjjflmc(Optional.ofNullable(nkRsYszbtz.getFbmjjflmc()).orElseGet(()->""));
        nkRsXmyszbb.setFzfjjflmc(Optional.ofNullable(nkRsYszbtz.getFzfjjflmc()).orElseGet(()->""));
        nkRsXmyszbb.setFystzmc(Optional.ofNullable(nkRsYszbtz.getFysxmmc()).orElseGet(()->""));
        nkRsXmyszbb.setFnd(DateConversionUtils.DateToYear(new Date()));
        nkRsXmyszbb.setId(GetUuIdUtils.ReplaceUuId());
        nkRsXmyszbb.setParentid(nkCfVo.getFtzid());

        if (StringUtils.isBlank(nkCfVo.getFtzid())){
            throw new BusinessException("操作失败，台账参数为空！");
        }

        //预算指标状态 默认为启用
        if (StringUtils.isBlank(nkCfVo.getFyszbzt())){
            nkRsXmyszbb.setFyszbzt(NkConstant.ZBZT_QY);
        }

        if (StringUtils.isBlank(nkRsXmyszbb.getFyzfje())){
            nkRsXmyszbb.setFyzfje("0");
        }

        if (StringUtils.isBlank(nkRsXmyszbb.getFzbjy())){
            nkRsXmyszbb.setFzbjy("0");
        }

        if (StringUtils.isBlank(nkRsXmyszbb.getFzcjd())){
            nkRsXmyszbb.setFzcjd("0");
        }

        BigDecimal zzbBd = new BigDecimal(nkRsXmyszbb.getFzzb());
        BigDecimal yzfje = new BigDecimal(nkRsXmyszbb.getFyzfje());

        if ((zzbBd.compareTo(yzfje)) == -1){
            throw new BusinessException("支付金额不能比总指标大！");
        }

        BigDecimal zbjyBd = zzbBd.subtract(yzfje);
        nkRsXmyszbb.setFzbjy(String.valueOf(zbjyBd));

        BigDecimal initZcjd = yzfje.divide(zzbBd, 3, BigDecimal.ROUND_HALF_UP);
        nkRsXmyszbb.setFzcjd(String.valueOf(initZcjd));
        nkRsXmyszbbService.save(nkRsXmyszbb);
        // 拆分后开始处理台账表业务  每拆分一次 就加一次 如果拆分的数据等于1 就是第一次拆分
        // 查询此台账下的拆分项目
        List<NkRsXmyszbb> xmyszbbList = nkRsXmyszbbService.list(new LambdaQueryWrapper<NkRsXmyszbb>()
                .eq(NkRsXmyszbb::getFtzid, nkCfVo.getFtzid()));



        if (CollectionUtil.isEmpty(xmyszbbList) || xmyszbbList.size() == 0){
           // 已支付金额 和 已申请支付金额 为vo里面拆分的总指标
           nkRsYszbtz.setFyzfje(nkCfVo.getFzzb());
           nkRsYszbtz.setFysqzfje(nkCfVo.getFzzb());
           //指标结余（总指标-已支付金额）
           String fzzb = nkRsYszbtz.getFzzb(); // 总指标
           String cffzzb = nkCfVo.getFzzb(); // 拆分的总指标

            BigDecimal v = new BigDecimal(fzzb);
            BigDecimal v1 = new BigDecimal(cffzzb);

            BigDecimal zbjy = v.subtract(v1);


           //支出进度 已支付金额/总指标
            BigDecimal zcjd = v1.divide(v, 3, BigDecimal.ROUND_HALF_UP);

            nkRsYszbtz.setFzcjd(String.valueOf(zcjd));
            nkRsYszbtz.setFzbjy(String.valueOf(zbjy));

            nkRsYszbtz.setFsfywqcf(NkConstant.NK_CWYS_YCF);
            nkRsYszbtzService.updateById(nkRsYszbtz);

       }else {
            //先拿到原本的已支付金额 和 已申请支付金额
            //老的已支付金额
            BigDecimal oldfyzfje = new BigDecimal(nkRsYszbtz.getFyzfje()); //老的已支付金额
            BigDecimal oldfysqzfje = new BigDecimal(nkRsYszbtz.getFysqzfje()); //老的已申请支付金额


            //新的已支付金额 和 已申请支付金额 为 vo里面的总指标
            BigDecimal newfyzfje = new BigDecimal(nkCfVo.getFzzb());  // 新的已支付金额
            BigDecimal newfysqzfje = new BigDecimal(nkCfVo.getFzzb()); // 新的已申请支付金额

            //老的 + 新拆分的 为当前的 相加
            BigDecimal nowfyzfje = oldfyzfje.add(newfyzfje); // 当前已支付金额
            BigDecimal nowfysqzfje = oldfysqzfje.add(newfysqzfje);

            //指标结余
            BigDecimal zzb = new BigDecimal(nkRsYszbtz.getFzzb());  //总指标
            BigDecimal zbjy = zzb.subtract(nowfyzfje);  // 指标结余

            //支出进度
            BigDecimal zcjd = nowfyzfje.divide(zzb, 3, BigDecimal.ROUND_HALF_UP);

            nkRsYszbtz.setFyzfje(String.valueOf(nowfyzfje));
            nkRsYszbtz.setFysqzfje(String.valueOf(nowfysqzfje));
            nkRsYszbtz.setFzbjy(String.valueOf(zbjy));
            nkRsYszbtz.setFzcjd(String.valueOf(zcjd));

            // 已支付 = 总指标 = 0 完成拆分
           if ((nowfyzfje.compareTo(zzb)) == 0){
               nkRsYszbtz.setFsfywqcf(NkConstant.NK_CWYS_YCFWC);
           }else {
               nkRsYszbtz.setFsfywqcf(NkConstant.NK_CWYS_YCF);
           }

           nkRsYszbtzService.updateById(nkRsYszbtz);
       }

        String zy = "";
        zy += Optional.ofNullable(nkRsYszbtz.getFysxmmc()).orElseGet(()->"");
        zy += "/";
        zy += "总指标: " + Optional.ofNullable(nkRsYszbtz.getFzzb()).orElseGet(()->"0");
        zy += "/";
        zy += "指标结余["+Optional.ofNullable(nkRsYszbtz.getFzbjy()).orElseGet(()->"0")+"]";

        nkRsYszbczjlService.addczjl(NkConstant.CZFS_CSHDR,nkCfVo.getFtzid(),zy,NkConstant.SZLX_SR,nkCfVo.getFzzb(),nkRsXmyszbb.getId(),nkCfVo.getFtzid());
       return HttpResult.ok("拆分成功");
    }


    /**
     * 查询药品监督管理局下部门
     */
    @AutoLog(value = "查询药品监督管理局下部门")
    @ApiOperation(value = "查询药品监督管理局下部门")
    @GetMapping(value = "/selectypjddepart")
    public HttpResult<?> selectYpjdDepart() {

        List<YcSysOrg> list = ycSysOrgService.list(new LambdaQueryWrapper<YcSysOrg>().eq(YcSysOrg::getParentId, NkConstant.SPZX));
        return HttpResult.ok(list);

    }

    @AutoLog(value = "内控-预算指标台账-通过id删除")
    @ApiOperation(value = "内控-预算指标台账-通过id删除")
    @DeleteMapping(value = "/delete")
    public HttpResult<?> delete(@RequestParam(value = "id",defaultValue = "") String id) {
        if (StringUtils.isBlank(id)){
            throw new BusinessException("参数为空！");
        }

        NkRsYszbtz tz = nkRsYszbtzService.getById(id);
        if (tz == null){
            throw new BusinessException("没有相匹配的台账数据！");
        }

        if (tz.getFsfywqcf() == null || tz.getFsfywqcf() == 0){
            nkRsYszbtzService.removeById(id);
        }else {
            throw new BusinessException("台账已使用，无权限删除！");
        }

        return HttpResult.ok(I18nUtil.message("delete.success"));
    }

    @AutoLog(value = "内控-预算指标台账-批量删除")
    @ApiOperation(value = "内控-预算指标台账-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public HttpResult<?> deleteBatch(@RequestParam(value = "ids",defaultValue = "") String ids) {
        if (StringUtils.isBlank(ids)){
            throw new BusinessException("参数为空！");
        }
        List<NkRsYszbtz> list = nkRsYszbtzService.listByIds(Arrays.asList(ids.split(",")));
        if (CollectionUtil.isNotEmpty(list)){
            String msg = "";
            for (NkRsYszbtz tz : list){
                if (tz.getFsfywqcf() == null || tz.getFsfywqcf() == 0){
                    nkRsYszbtzService.removeById(tz.getId());
                }else {
                    msg += tz.getFysxmmc() + "已经在使用无法删除！";
                }
            }
            if (StringUtils.isNotBlank(msg)){
                throw new BusinessException(msg);
            }
        }else {
            throw new BusinessException("没有相匹配的台账数据！");
        }

        return HttpResult.ok(I18nUtil.message("delete.success"));
    }


    @AutoLog(value = "内控-预算指标台账-通过id查询")
    @ApiOperation(value = "内控-预算指标台账-通过id查询")
    @GetMapping(value = "/queryById")
    public HttpResult<?> queryById(@RequestParam("id") String id) {
        NkRsYszbtz nkRsYszbtz = nkRsYszbtzService.getById(id);
        return HttpResult.ok(nkRsYszbtz);
    }

    @Log(title = "导入台账数据-表格excel")
    @ApiOperation(value = "导入台账数据-表格excel")
    @PostMapping(value = "impNktzData")
    public HttpResult<?> impNktzData(@RequestParam("file") MultipartFile file){
        if (file.isEmpty()){
            return HttpResult.error("文件不存在");
        }

        //获取文件名
        String fileName = file.getOriginalFilename();
        //判断文件类型，这里我们只要xls文件
        if (fileName != null && !fileName.endsWith(".xls") && !fileName.endsWith(".xlsx"))
            return HttpResult.error(1, "请选择“xls”或“xlsx”文件");

        File fileUpload = oaLocalFileUploadUtils.uploadDempFile(file,fileName);
        // 获取导入的数据
        List<Map<String, Object>> mapsList = null;
        try {
            mapsList = myExclUtil.paresExclToMapList(OaBusinessConstant.IMPORT_NK_NKRSYSZBTZ_XML, fileUpload);
        } catch (Exception e) {
            log.error("导入台账数据出错-{}",e.getMessage());
        }
        String msg = "";
        if (CollectionUtils.isNotEmpty(mapsList) && mapsList.size() > 0) {
            int count = 1;
            for (Map map : mapsList) {
                NkRsYszbtz nkRsYszbtz = new NkRsYszbtz();
                BeanUtil.copyProperties(map,nkRsYszbtz);
                nkRsYszbtz.setId(GetUuIdUtils.ReplaceUuId());

                if (StringUtils.isBlank(nkRsYszbtz.getFyzfje())){
                    nkRsYszbtz.setFyzfje("0");
                }
                if (StringUtils.isBlank(nkRsYszbtz.getFzbjy())){
                    nkRsYszbtz.setFzbjy("0");
                }
                if (StringUtils.isBlank(nkRsYszbtz.getFzcjd())){
                    nkRsYszbtz.setFzcjd("0");
                }

                if (StringUtils.isBlank(nkRsYszbtz.getFnd())){
                    nkRsYszbtz.setFnd(DateConversionUtils.DateToYear(new Date()));
                }
                BigDecimal zzbBd = new BigDecimal(nkRsYszbtz.getFzzb() == null ? "0" : nkRsYszbtz.getFzzb());
                BigDecimal yzfje = new BigDecimal(nkRsYszbtz.getFyzfje() == null ? "0" : nkRsYszbtz.getFyzfje());

                if ((zzbBd.compareTo(yzfje)) == -1){
                    msg += "第【"+count+"】条，总指标小于已支付金额; \n";
                    continue;
                }

                BigDecimal zbjyBd = zzbBd.subtract(yzfje);
                nkRsYszbtz.setFzbjy(String.valueOf(zbjyBd));

                nkRsYszbtz.setFsfywqcf(NkConstant.NK_CWYS_WCF);
                nkRsYszbtzService.save(nkRsYszbtz);
                String operContent = "新增导入信息：";
                Map<String, Object> bhgzMap = ObjectToMapUtils.objectToMap(nkRsYszbtz);
                operContent += LogUtils.MapToStringMethod(bhgzMap);
                spcyLogService.addLogs(OaLogConstant.LOGS_NK_YSZBTZ,operContent,nkRsYszbtz.getId(), OaLogConstant.LOGS_NK_YSZBTZ, OaCommonFlowConstant.LOGS_SYS_TYPE_XZ);
            }
        }
        fileUpload.delete();

        if (StringUtils.isNotBlank(msg)){
            throw new BusinessException(msg);
        }

        return HttpResult.ok("导入成功");
    }

    /**
     * 下载 导入模板
     * @param response
     */
    @AutoLog(value = "下载-导入模板")
    @ApiOperation(value = "下载-导入模板")
    @GetMapping("/getImpInspectorModel")
    public void getImpInspectorModel(HttpServletResponse response){
        try {
            response.setContentType("application/ms-excel;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode("内控台账模板.xls", "UTF-8"))));
            OutputStream out = response.getOutputStream();
            myExclUtil.buildImpModel(OaBusinessConstant.IMPORT_NK_NKRSYSZBTZ_XML, out);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @AutoLog(value = "导出预算指标台账数据-表格excel")
    @ApiOperation(value = "导出预算指标台账数据-表格excel")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "ids",value = "主键id字符逗号分割",required = true)
    })
    @GetMapping("/exportYszbtzData")
    public void exportYszbtzData(@RequestParam(value = "ids",defaultValue = "")String ids,
                                 NkRsYszbtz ndkpBasic,
                               HttpServletResponse response){
        try {
            String name = "exportYszbtzData";
            response.setContentType("application/ms-excel;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename="
                    .concat(String.valueOf(URLEncoder.encode(name+".xls", "UTF-8"))));
            OutputStream out = response.getOutputStream();

            List<String> IdsList = Arrays.asList(ids.split(","));
            List<Object> list = new ArrayList<>(); // 导出的数据
            // 多选导出
            if (StringUtils.isNotEmpty(ids)) {
                List<NkRsYszbtz> ndkpBasicList = nkRsYszbtzService.listByIds(IdsList);
                if (CollectionUtils.isNotEmpty(ndkpBasicList)){
                    for (NkRsYszbtz e : ndkpBasicList){
                        list.add(e);
                    }
                }
            }else {
                LambdaQueryWrapper<NkRsYszbtz> queryWrapper = new LambdaQueryWrapper<>();
                //预算项目名称
                queryWrapper.like(StringUtils.isNotBlank(ndkpBasic.getFysxmmc()),NkRsYszbtz::getFysxmmc,ndkpBasic.getFysxmmc());
                //指标摘要
                queryWrapper.like(StringUtils.isNotBlank(ndkpBasic.getFzbzy()),NkRsYszbtz::getFzbzy,ndkpBasic.getFzbzy());
                //功能分类编码
                queryWrapper.like(StringUtils.isNotBlank(ndkpBasic.getFgnflbm()),NkRsYszbtz::getFgnflbm,ndkpBasic.getFgnflbm());
                //功能分类名称
                queryWrapper.like(StringUtils.isNotBlank(ndkpBasic.getFgnflmc()),NkRsYszbtz::getFgnflmc,ndkpBasic.getFgnflmc());
                //部门经济分类编码
                queryWrapper.like(StringUtils.isNotBlank(ndkpBasic.getFbmjjflbm()),NkRsYszbtz::getFbmjjflbm,ndkpBasic.getFbmjjflbm());
                //部门经济分类名称
                queryWrapper.like(StringUtils.isNotBlank(ndkpBasic.getFbmjjflmc()),NkRsYszbtz::getFbmjjflmc,ndkpBasic.getFbmjjflmc());
                //政府经济分类编码
                queryWrapper.like(StringUtils.isNotBlank(ndkpBasic.getFzfjjflbm()),NkRsYszbtz::getFzfjjflbm,ndkpBasic.getFzfjjflbm());
                //政府经济分类名称
                queryWrapper.like(StringUtils.isNotBlank(ndkpBasic.getFzfjjflmc()),NkRsYszbtz::getFzfjjflmc,ndkpBasic.getFzfjjflmc());
                //支出项目类别编码
                queryWrapper.like(StringUtils.isNotBlank(ndkpBasic.getFzcxmlbbm()),NkRsYszbtz::getFzcxmlbbm,ndkpBasic.getFzcxmlbbm());
                //支出项目类别名称
                queryWrapper.like(StringUtils.isNotBlank(ndkpBasic.getFzcxmlbmc()),NkRsYszbtz::getFzcxmlbmc,ndkpBasic.getFzcxmlbmc());
                //指标来源名称
                queryWrapper.like(StringUtils.isNotBlank(ndkpBasic.getFzblymc()),NkRsYszbtz::getFzblymc,ndkpBasic.getFzblymc());
                //预算来源名称
                queryWrapper.like(StringUtils.isNotBlank(ndkpBasic.getFyslymc()),NkRsYszbtz::getFyslymc,ndkpBasic.getFyslymc());
                //是否已完全拆分
                if (ndkpBasic.getFsfywqcf() != null){
                    queryWrapper.like(NkRsYszbtz::getFsfywqcf,ndkpBasic.getFsfywqcf());
                }
                List<NkRsYszbtz> ndkpBasicList = nkRsYszbtzService.list(queryWrapper);
                // 条件导出
                if (CollectionUtils.isNotEmpty(ndkpBasicList)){
                    for (NkRsYszbtz e : ndkpBasicList){
                        list.add(e);
                    }
                }
            }
            myExclUtil.outputListToExclFile(OaBusinessConstant.IMPORT_NK_NKRSYSZBTZ_XML,list,out); // 导出模板数据成excel
        } catch (Exception e) {
            log.error("导出预算指标台账数据出错-{}",e.getMessage());
        }
    }


    /**
     * 柱形图组装数据
     */
    @AutoLog(value = "柱形图组装数据")
    @ApiOperation(value = "柱形图组装数据")
    @GetMapping("/zxtsj")
    public HttpResult<?> zxtsj(){
        Map map = new HashMap();
        List list = new ArrayList();
        List list1 = new ArrayList();
        List list2 = new ArrayList();

        List<NkRsYszbtz> yslist = nkRsYszbtzService.list(new LambdaQueryWrapper<NkRsYszbtz>()
                .orderByAsc(NkRsYszbtz::getFxh));

        for (NkRsYszbtz ystzmc:yslist){
            String fysxmmc = ystzmc.getFysxmmc();
            String fyzfje = ystzmc.getFyzfje();
            String fzbjy = ystzmc.getFzbjy();

            list.addAll(Collections.singleton(fysxmmc));
            list1.addAll(Collections.singleton(fyzfje));
            list2.addAll(Collections.singleton(fzbjy));
        }
        map.put("fysxmmc",list );
        map.put("fyzfje",list1);
        map.put("fzbjy", list2);


        return HttpResultVo.HttpResultList(map);
    }

}
